<?php
// 文件夹和文件查询控制器
namespace App\Http\Controllers\FileControllers;

use App\Http\Controllers\Controller;
use App\Models\File;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Http\JsonResponse;
use App\Models\DataTableModel\Icon;
use App\Models\DataTableModel\Folder;
use Illuminate\Database\Eloquent\ModelNotFoundException; // 引入模型未找到的异常类 
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Collection;

class FileQueriesControllers extends Controller
{
    public function queries(Request $request, $user_id) // 你可以添加一个默认的分页大小  
    {
        try {
            $perPage = $request->input('perPage', 10); // 默认每页10条  
            // 使用 paginate 方法实现分页查询  
            $files = File::where('user_id', $user_id)
                ->where('file_state', 'ON') // 排除 file_state 为 OFF 的文件  
                ->with('icon')
                ->paginate($perPage);

            // 检查是否有数据  
            if ($files->isEmpty()) {
                // 如果没有文件，返回一个特定的响应  
                return response()->json(['message' => '未找到用户的文件'], 200);
            }

            // 将集合转换为数组，不需要添加序号，因为 Vue 可以通过索引访问  
            $filesArray = $files->map(function ($file) {
                return [
                    'id' => $file->id,
                    'file_name' => $file->file_name,
                    'updated_at' => $file->updated_at->format('Y-m-d H:i'),
                    'file_image_id' => $file->file_image_id,
                    'icon_url' => 'http://127.0.0.1:8000/storage/image/icon/' . optional($file->icon)->icon_data, // 添加了前缀的URL  
                    'file_parent_folder_id' => $file->file_parent_folder_id,
                    'icon_data' => optional($file->icon)->icon_data, // 使用optional防止尝试访问null对象的属性  
                    'file_size' => $file->file_size,
                    // ... 其他需要的字段  
                ];
            })->toArray();

            // 返回包含分页信息的响应  
            // 注意：通常我们不会把分页集合直接转换为数组并返回，因为这样会丢失分页信息  
            // 但是，如果你确实需要这样做，可以手动添加分页信息到响应中  
            $responseData = [
                'data' => $filesArray,
                'pagination' => [
                    'total' => $files->total(),
                    'per_page' => $files->perPage(),
                    'current_page' => $files->currentPage(),
                    'last_page' => $files->lastPage(),
                    // ... 其他分页信息  
                ],
            ];

            return response()->json($responseData);
        } catch (ModelNotFoundException $e) {
            // 如果模型未找到，返回一个自定义的响应  
            return response()->json(['message' => '用户未定义'], 404);
        } catch (\Exception $e) {
            // 捕获其他类型的异常  
            if (config('app.debug')) {
                // 在开发环境中，返回详细的错误信息并记录到日志  
                // \Log::error('检索文件时出错: ' . $e->getMessage() . "\n" . $e->getTraceAsString());  
                return response()->json([
                    'message' => '检索文件时出错',
                    'error' => [
                        'message' => $e->getMessage(), // 具体的错误消息  
                        'file' => $e->getFile(), // 错误发生的文件  
                        'line' => $e->getLine(), // 错误发生的行号  
                        'trace' => explode("\n", $e->getTraceAsString()), // 完整的堆栈跟踪，仅用于开发环境  
                    ],
                    'code' => $e->getCode(), // 错误代码  
                ], 500);
            } else {
                // 在生产环境中，仅记录错误到日志并返回通用的错误响应  
                // \Log::error('检索文件时出错: ' . $e->getMessage());  
                return response()->json(['message' => '服务器内部错误，请稍后再试'], 500);
            }
        }
    }


    public function filefolder(Request $request, $user_id, $parentFolderId = null)
    {
        try {
            $perPage = $request->input('perPage', 10);
            $page = $request->input('page', 1);

            // 查询文件夹,如果parentFolderId为null,
            $foldersQuery = Folder::where('id', $user_id);
            if (is_null($parentFolderId)) {
                $rootFolderId = Folder::where('id', $user_id)
                    ->whereNull('parent_folder_id')
                    ->value('folder_id');
                if (!$rootFolderId) {
                    throw new \Exception('找不到用户根文件夹id');
                }
                $foldersQuery->where('parent_folder_id', $rootFolderId)
                    ->where('folder_state', 'ON'); // 排除 file_state 为 OFF 的文件  
            } else {
                $foldersQuery->where('parent_folder_id', $parentFolderId)
                    ->where('folder_state', 'ON'); // 排除 file_state 为 OFF 的文件  
            }
            $folders = $foldersQuery->get();

            // 查询文件  
            $files = File::where('user_id', $user_id);
            if (!is_null($parentFolderId)) {
                $files->where('file_parent_folder_id', $parentFolderId)
                    ->where('file_state', 'ON'); // 排除 file_state 为 OFF 的文件  
            } else {
                // 获取根目录下的文件ID逻辑（略）  
            }
            $files = $files->get();

            // 处理文件夹和文件数据
            $folderData = $folders->map(function ($folder) {
                return [
                    'id' => $folder->folder_id,
                    // 为了适应前台分页，做的补救措施，这里是个败笔！！！！1
                    'file_name' => $folder->folder_name,
                    'updated_at' => $folder->updated_at->format('Y-m-d H:i'),
                    'file_image_id' => $folder->folder_image_id,
                    'icon_url' => 'http://127.0.0.1:8000/storage/image/icon/' . optional($folder->folder_icon)->icon_data, // 添加了前缀的URL  
                    // 文件夹没有文件大小，所以可以设置为null或者省略该字段  
                    'file_size' => $folder->storage_space,
                    // ... 其他需要的字段，例如类型、图标等  
                    'type' => 'folder', // 添加一个字段来区分是文件夹还是文件  
                ];
            })->all();

            $fileData = $files->map(function ($file) {
                return [
                    'id' => $file->id,
                    'file_name' => $file->file_name,
                    'updated_at' => $file->updated_at->format('Y-m-d H:i'),
                    'file_image_id' => $file->file_image_id,
                    'icon_url' => 'http://127.0.0.1:8000/storage/image/icon/' . optional($file->icon)->icon_data, // 添加了前缀的URL  
                    'file_size' => $file->file_size,
                    // ... 其他需要的字段  
                    'type' => 'file',
                ];
            })->all();

            $combinedData = Collection::make($folderData)
                ->merge($fileData);

            // 实现自定义分页逻辑  
            $offset = ($page - 1) * $perPage;
            $paginatedData = array_slice($combinedData->toArray(), $offset, $perPage);

            // 创建自定义的分页对象（如果需要完整的分页功能）  
            $total = count($combinedData);
            $lastPage = ceil($total / $perPage);
            $paginator = new LengthAwarePaginator($paginatedData, $total, $perPage, $page, [
                'path' => request()->url(),
                'query' => request()->query(),
            ]);

            // 准备响应数据  
            $responseData = [
                'data' => $paginator->items(),
                'pagination' => [
                    'total' => $paginator->total(),
                    'per_page' => $paginator->perPage(),
                    'current_page' => $paginator->currentPage(),
                    'last_page' => $paginator->lastPage(),
                ],
            ];

            // 返回响应数据给前端  
            return response()->json($responseData);
        } catch (ModelNotFoundException $e) {
            // 如果模型未找到，返回一个自定义的响应  
            return response()->json(['message' => '用户未定义'], 404);
        } catch (\Exception $e) {
            // 捕获其他类型的异常  
            if (config('app.debug')) {
                // 在开发环境中，返回详细的错误信息并记录到日志  
                // \Log::error('检索文件时出错: ' . $e->getMessage() . "\n" . $e->getTraceAsString());  
                return response()->json([
                    'message' => '检索文件时出错',
                    'error' => [
                        'message' => $e->getMessage(), // 具体的错误消息  
                        'file' => $e->getFile(), // 错误发生的文件  
                        'line' => $e->getLine(), // 错误发生的行号  
                        'trace' => explode("\n", $e->getTraceAsString()), // 完整的堆栈跟踪，仅用于开发环境  
                    ],
                    'code' => $e->getCode(), // 错误代码  
                ], 500);
            } else {
                // 在生产环境中，仅记录错误到日志并返回通用的错误响应  
                // \Log::error('检索文件时出错: ' . $e->getMessage());  
                return response()->json(['message' => '服务器内部错误，请稍后再试'], 500);
            }
        }
    }


    public function file_folder(Request $request, $user_id)
    {
        try {
            $perPage = $request->input('perPage', 10);
            $page = $request->input('page', 1);
            $parentFolderId = $request->input('parentFolderId', null);

            // 计算偏移量  
            $offset = ($page - 1) * $perPage;

            // 根据当前的用户id计算出sql语句查询中所需要的数据
            if (is_null($parentFolderId)) {
                $rootFolderId = Folder::where('id', $user_id)
                    ->whereNull('parent_folder_id')
                    ->value('folder_id');
                if (!$rootFolderId) {
                    throw new \Exception('找不到用户根文件夹id');
                }
                $parentFolderId = $rootFolderId;
            }

            // 构建原始的 SQL 查询，包含 UNION ALL 和 LIMIT/OFFSET  
            $sql = "  
                SELECT * FROM (  
                    (SELECT folder_id AS id, folder_name AS file_name, NULL AS file_size, folder_image_id, updated_at, 'folder' AS source   
                    FROM folders  
                    WHERE folder_state = 'ON'  
                    " . ($parentFolderId ? "AND parent_folder_id = ?" : "") . ")  
                    UNION ALL  
                    (SELECT id, file_name AS file_name, file_size, file_image_id, updated_at, 'file' AS source  
                    FROM files  
                    WHERE file_state = 'ON'  
                    " . ($parentFolderId ? "AND file_parent_folder_id = ?" : "") . ")  
                ) AS combined_entries  
                LIMIT ?, ?";

            // 准备绑定参数  
            $bindings = [];
            if ($parentFolderId) {
                $bindings[] = $parentFolderId; // 如果提供了parentFolderId，绑定到两个子查询中  
                $bindings[] = $parentFolderId;
            }
            $bindings[] = $offset; // 绑定偏移量  
            $bindings[] = $perPage; // 绑定每页记录数  

            // 执行查询    
            $combinedData = DB::select($sql, $bindings);

            $iconUrlPrefix = "http://127.0.0.1:8000/storage/image/icon/";

            foreach ($combinedData as &$entry) {
                $entry->icon_url = null; // 初始化icon_url字段  

                if ($entry->source === 'folder' && !empty($entry->folder_image_id)) {
                    // 查找folder图标  
                    $icon = Icon::where('id', $entry->folder_image_id)->first();
                    if ($icon) {
                        $entry->icon_url = $iconUrlPrefix . $icon->icon_data;
                    }
                } elseif ($entry->source === 'file' && !empty($entry->folder_image_id)) {
                    // 查找file图标  
                    // 多表联合查询之后，file_image_id字段变为了folder_image_id！！！！！
                    $icon = Icon::where('id', $entry->folder_image_id)->first();
                    if ($icon) {
                        $entry->icon_url = $iconUrlPrefix . $icon->icon_data;
                    }
                }
            }
            unset($entry); // 取消引用



            // 计算总数的查询
            // 计算总记录数的查询  
            $countSql = "  
            SELECT COUNT(*) as total_count FROM (  
                (SELECT 1 FROM folders WHERE folder_state = 'ON' " . ($parentFolderId ? "AND parent_folder_id = ?" : "") . ")  
                UNION ALL  
                (SELECT 1 FROM files WHERE file_state = 'ON' " . ($parentFolderId ? "AND file_parent_folder_id = ?" : "") . ")  
            ) AS combined_counts";

            // 准备绑定参数（仅用于$parentFolderId不为null的情况）  
            $countBindings = [];
            if ($parentFolderId) {
                $countBindings[] = $parentFolderId; // 绑定到两个子查询中  
                $countBindings[] = $parentFolderId;
            }

            // 执行查询获取总记录数  
            $totalCountResult = DB::select($countSql, $countBindings)[0]->total_count;

            // 现在你可以使用$totalCountResult来构建你的响应数据了  
            $responseData = [
                'data' => $combinedData, // 分页后的数据  
                'pagination' => [
                    'total' => $totalCountResult, // 总记录数  
                    'per_page' => $perPage,
                    'current_page' => $page,
                    'last_page' => ceil($totalCountResult / $perPage),
                ],
            ];

            // 返回响应数据给前端  
            return response()->json($responseData);
        } catch (ModelNotFoundException $e) {
            // 如果模型未找到，返回一个自定义的响应  
            return response()->json(['message' => '用户未定义'], 404);
        } catch (\Exception $e) {
            // 捕获其他类型的异常  
            if (config('app.debug')) {
                // 在开发环境中，返回详细的错误信息并记录到日志  
                // \Log::error('检索文件时出错: ' . $e->getMessage() . "\n" . $e->getTraceAsString());  
                return response()->json([
                    'message' => '检索文件时出错',
                    'error' => [
                        'message' => $e->getMessage(), // 具体的错误消息  
                        'file' => $e->getFile(), // 错误发生的文件  
                        'line' => $e->getLine(), // 错误发生的行号  
                        'trace' => explode("\n", $e->getTraceAsString()), // 完整的堆栈跟踪，仅用于开发环境  
                    ],
                    'code' => $e->getCode(), // 错误代码  
                ], 500);
            } else {
                // 在生产环境中，仅记录错误到日志并返回通用的错误响应  
                // \Log::error('检索文件时出错: ' . $e->getMessage());  
                return response()->json(['message' => '服务器内部错误，请稍后再试'], 500);
            }
        }
    }
}
